#include "internal.h"
#include "Defines.h"
#include "DeviceProperty.h"
#include "PortableDeviceProps.h"
#include "ObjectLock.h"
#include "SensorDdi.h"
#include "Sensor.h"
#include "SensorRegistry.h"
#include "Client.h"
#include "DataQueue.h"
#include "Thread.h"
#include "ClientsManager.h"
#include "Dummy.h"
#include "Dummy.tmh"

//
// single dummy instance
//
CDummy CDummy::s_Dummy;

CDummy::CDummy(void)
{
}

CDummy::~CDummy(void)
{
	//
	// stop events processing thread if it is running
	//
	notifyTerminate();
	if(getExitCode() == STILL_ACTIVE)
	{
		if(WaitForSingleObject(getHandle(), 2000) == WAIT_TIMEOUT)
			stop();
	}
}

CDummy& CDummy::GetDummy()
{
	return CDummy::s_Dummy;
}

float Float(char *const p)
{
	float val;
	memcpy(&val,p,sizeof val);
	return val;
}

unsigned long CDummy::run()
{
	HANDLE hPipe;
	LPTSTR PipeName = TEXT("\\\\.\\pipe\\Accelerometer");

	hPipe = CreateNamedPipe(
		PipeName,
		PIPE_ACCESS_INBOUND,
        PIPE_TYPE_MESSAGE | PIPE_WAIT,  
        PIPE_UNLIMITED_INSTANCES ,
        1024,
        1024,
        5000,
        NULL);
   
	if( hPipe == NULL )
	{
		//cerr<<"Error: cannot create named pipe\n";
		return 1;
	}

	while(true)
	{
		while (ConnectNamedPipe(hPipe, NULL) )
		{
			const int bufferSize = 3*sizeof(float);
			char  buf[bufferSize];
			DWORD bread;
			while( ReadFile(hPipe, (void*)buf, bufferSize, &bread, NULL) )
			{
				float x = Float(buf);
				float y = Float(buf+sizeof(float));
				float z = Float(buf+2*sizeof(float));
				PostData(x, y, z);
			}
			DisconnectNamedPipe(hPipe);
		}

		//// generate data
		////
		//PostData(1,-1,0);

		// sleeps 1 second
		sleep(1000);

		// check for termination
		DWORD dwStatus = WaitForSingleObject(hTerminateEvent, 0);
	
		if (dwStatus == WAIT_OBJECT_0)
		{
			return 0L;
		}
	}

	return 0L;
}

//
// Accelerometer ID.
//
wstring CDummy::GetId() const
{
	return L"Accelerometer";
}

void CDummy::PostData(FLOAT x, FLOAT y, FLOAT z)
{
	CClientsManager& cm = CClientsManager::GetClientsManager();
	if(cm.CanRaiseEvents())
	{
		//
		// construct the properties collection
		//
		vector<CDeviceProperty> props(3);
		props[0] = CDeviceProperty(SENSOR_DATA_TYPE_ACCELERATION_X_G, x);
		props[1] = CDeviceProperty(SENSOR_DATA_TYPE_ACCELERATION_Y_G, y);
		props[2] = CDeviceProperty(SENSOR_DATA_TYPE_ACCELERATION_Z_G, z);

		//
		// raise the event
		//
		cm.PostDataEvent(GetId(), props);
	}
}